package com.zqwh.yj.sdk.model;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;

import com.zkteco.android.biometric.core.device.ParameterHelper;
import com.zkteco.android.biometric.core.device.TransportType;
import com.zkteco.biometric.ZKWFPModule;
import com.zkteco.biometric.ZKWFPModuleFactory;
import com.zkteco.biometric.exception.ZKWFPModuleException;
import com.zqwh.yj.sdk.utils.LogUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

public class FingerprintModelImpl implements FingerprintModel {
    private final String ACTION_USB_PERMISSION = "com.zkteco.finger.USB_PERMISSION";

    private final int PID = 0x1001;
    private final int VID = 0xABCD;

    private ZKWFPModule module;
    private UsbManager usbManager = null;
    private Context context;
    private FingerprintInitListener initListener;
    private FingerprintDetectListener detectListener;
    private FingerprintCaptureListener captureListener;
    private FingerprintRegisterListener registerListener;
    private SmdtModel smdtModel;
    private int ioFingerDetect;
    private Timer timerDetectFinger;
    private int oldStatus = 0;

    boolean isRegister = false;
    private int time = 1;

    public FingerprintModelImpl(Context context) {
        this.context = context;
        startFingerSensor();
    }

    @Override
    public void setDetectListener(FingerprintDetectListener listener) {
        detectListener = listener;
    }

    @Override
    public void setCaptureListener(FingerprintCaptureListener listener) {
        captureListener = listener;
    }

    @Override
    public void setRegisterListener(FingerprintRegisterListener listener) {
        registerListener = listener;
    }

    private BroadcastReceiver usbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        LogUtils.error("USB已授权");
                        openDevice();
                    } else {
                        LogUtils.error("USB未授权");
                    }
                }
            }
        }
    };

    public void initDevice(int ioDetect, FingerprintInitListener l) {
        initListener = l;
        ioFingerDetect = ioDetect;

        usbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
        context.registerReceiver(usbReceiver, filter);

        boolean devFound = false;
        for (UsbDevice device : usbManager.getDeviceList().values()) {
            if (device.getVendorId() == VID && device.getProductId() == PID) {
                devFound = true;
                if(!usbManager.hasPermission(device)){
                    Intent intent = new Intent(ACTION_USB_PERMISSION);
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
                    usbManager.requestPermission(device, pendingIntent);
                }else{
                    openDevice();
                }
            }
        }
        if (!devFound){
            LogUtils.error("未找到指纹模块");
            initListener.onDeviceInitFinished(false);
        }
    }

    private void startFingerSensor() {
        // Start fingerprint sensor
        Map fingerprintParams = new HashMap();
        //set vid
        fingerprintParams.put(ParameterHelper.PARAM_KEY_VID, VID);
        //set pid
        fingerprintParams.put(ParameterHelper.PARAM_KEY_PID, PID);
        module = ZKWFPModuleFactory.createFingerprintSensor(context, TransportType.USBSCSI, fingerprintParams);
    }

    public void openDevice(){
        try {
            module.open(0);
            module.writeSystemParam(0,4,0);
            LogUtils.logout("指纹设备连接成功:    FirmwareVersion:"+module.getFirmwareVersion()+" SerialNumber:"+module.getSerialNumber());
            if (initListener != null){
                initListener.onDeviceInitFinished(true);
                startDetectFinger();
            }
        } catch (ZKWFPModuleException e) {
            e.printStackTrace();
            if (initListener != null){
                initListener.onDeviceInitFinished(false);
            }
        }
    }

    private void startDetectFinger() {
        smdtModel = new SmdtModelImpl(context);
        //输入 默认低电平
        smdtModel.setInternalGpioDirection(ioFingerDetect, 0, 0);
        timerDetectFinger = new Timer(true);
        timerDetectFinger.schedule(new TimerTask() {
            public void run() {
                int newStatus = smdtModel.getInternalGpioValue(ioFingerDetect);

                if (newStatus != oldStatus){
                    if (newStatus == 1){
                        if (detectListener != null){
                            detectListener.onFingerPut();
                        }
                    }else {
                        if (detectListener != null){
                            detectListener.onFingerLeave();
                        }
                    }
                }
                oldStatus = newStatus;
            }
        },0, 500);
    }

    public void captureFinger(){
        try {
            int ret = module.captureFinger(0);
            if(0 == ret){
                int[] id = new int[1];
                ret = module.identify(0,id);
                if(ret == 0x100A){
                    if (captureListener != null){
                        captureListener.fingerprintNotFound();
                    }
                }else if(ret == 0x1008||ret == 0xFFFF){
                    if (captureListener != null){
                        captureListener.fingerprintCaptureFail();
                    }
                }else if(ret == 0x0000){
                    if (captureListener != null){
                        captureListener.fingerprintCaptureSuccess(id[0]);
                    }
                }
            }else if(0x1012 == ret){
                if (captureListener != null){
                    captureListener.fingerprintNotCapture();
                }
            }
        } catch (ZKWFPModuleException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void register(final int id) {
        if(isRegister){
            if (registerListener != null){
                registerListener.onRegisterErrorInRegister();
            }
        }

        if (registerListener != null){
            registerListener.onCaptureFingerOneTime();
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                isRegister = true;
                while(isRegister){
                    try {
                        if(module.isPressFinger(0)){
                            if(time == 1){
                                if(0 == module.enrollStart(0,id)){
                                    if(0 == module.captureFinger(0)){
                                        if(0 == module.enroll1(0)){
                                            if (registerListener != null){
                                                registerListener.onCaptureFingerTwoTime();
                                            }
                                            time ++ ;
                                        }
                                    }
                                }else{
                                    if (registerListener != null){
                                        registerListener.onRegisterErrorIdRepeat();
                                    }
                                    break;
                                }
                            }else if(time == 2){
                                if(0 == module.captureFinger(0)){
                                    if(0 == module.enroll2(0)){
                                        if (registerListener != null){
                                            registerListener.onCaptureFingerThreeTime();
                                        }
                                        time ++ ;
                                    }
                                }
                            }else if(time == 3){
                                if(0 == module.captureFinger(0)){
                                    byte[] template = new byte[256];
                                    if(0 == module.enroll3(0,template)){
                                        if (registerListener != null){
                                            registerListener.onRegisterEnrollSuccess();
                                        }
                                    }else{
                                        if (registerListener != null){
                                            registerListener.onRegisterErrorEnrollFail();
                                        }
                                    }
                                }else{
                                    if (registerListener != null){
                                        registerListener.onRegisterErrorEnrollFail();
                                    }
                                }
                                break;
                            }
                        }
                    } catch (ZKWFPModuleException e) {
                        e.printStackTrace();
                    }
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                isRegister = false;
                time = 1;
            }
        }).start();
    }

    @Override
    public int delete(int id) {
        try {
            int ret = module.deleteID(0,id);
            if(ret == 0x0000){
                return 0;
            }else{
                LogUtils.logout("Delete result code : "+ret);
                return -1;
            }
        } catch (ZKWFPModuleException e) {
            e.printStackTrace();
            return -1;
        }
    }
}
